package com.budwk.app.sqfwV2.service.baiyunqu;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.exception.ServiceException;
import com.budwk.app.sqfw.constants.SqfwFormSummaryConstants;
import com.budwk.app.sqfw.models.PersonInfo;
import com.budwk.app.sqfw.models.Sqfw_completeflow;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.PersonInfoService;
import com.budwk.app.sqfw.services.SqfwCompleteflowService;
import com.budwk.app.sqfw.services.SqfwFormsummaryNewService;
import com.budwk.app.sqfw.vo.GenerateExcelUrlVO;
import com.budwk.app.sqfw.vo.GenerateWordAndPdfUrlVO;
import com.budwk.app.sqfwDoc.bo.ExcelCreateConfig;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.AbstractCustomerPdfCreateField;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.CommonParam;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.CompleteFlowPdfParamForController;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.PdfGenerateParam;
import com.budwk.app.sqfwDoc.codeGeneratorV2.generate.BasePdfGenerator;
import com.budwk.app.sqfwDoc.codeGeneratorV2.generate.ResultOfExcelGenerator;
import com.budwk.app.sqfwDoc.codeGeneratorV2.pdfService.CompleteFlowCommonPdfService;
import com.budwk.app.sqfwDoc.codeGeneratorV2.result.GeneratorPdfWordResult;
import com.budwk.app.sqfwDoc.dto.CompleteFlowTemplateCodeUpdateDTO;
import com.budwk.app.sqfwDoc.dto.TemplateCodeUpdateDTO;
import com.budwk.app.sqfwV2.component.SummarySafetyCommponent;
import com.budwk.app.sqfwV2.dto.baiyunqu.OldPeopleSeekPdfDTO;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.DownExcelLedgerReqVo;
import com.budwk.app.sqfwV2.dto.vo.SummaryQueryReqVo;
import com.budwk.app.sqfwV2.enums.OldPeopleSeekEnum;
import com.budwk.app.sqfwV2.generator.baiyunqv.OldPeopleSeekPdfGenerator;
import com.budwk.app.sqfwV2.service.SummarySafetyService;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.util.ClassUtil;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.adminUtils.CommonCheckUtils;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.starter.common.page.Pagination;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.security.utils.SecurityUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.policy.RenderPolicy;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Record;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.budwk.app.util.poiUtils.CommonFormOfficeUtils.createConvergePdfAndUpload;
import static com.budwk.app.util.poiUtils.CommonFormOfficeUtils.generateWordDocument;

/**
 * @author 东方祥云低代码1.1
 * @since 2024-03-12
 * <p>
 * 白云区特殊困难老年人探访 BaiYunQuOldPeopleSeek
 */
@IocBean
@Slf4j
public class OldPeopleSeekPdfService extends CompleteFlowCommonPdfService {

    @Inject
    SysUserService sysUserService;
    @Inject
    SqfwFormsummaryNewService sqfwFormsummaryNewService;
    @Inject
    SqfwCompleteflowService sqfwCompleteflowService;
    @Inject
    private SummarySafetyService summarySafetyService;
    @Inject
    private PersonInfoService personInfoService;
    @Inject
    private SummarySafetyCommponent summarySafetyCommponent;


    /**
     * 新增
     * @param dto
     */
    public void submitData(TemplateCodeUpdateDTO dto) {
        log.info("白云区老年人探访：{}", JSONUtil.toJsonStr(dto));
        CompleteFlowPdfParamForController paramForController = new CompleteFlowPdfParamForController();
        CompleteFlowTemplateCodeUpdateDTO completeFlowDataDTO = new CompleteFlowTemplateCodeUpdateDTO();

        // 设置上访时间
        Sqfw_formSummary_new formSummary = dto.getFormSummary();
        formSummary.setType(this.getSummaryType());
        OldPeopleSeekPdfDTO pdfDTO = JSONUtil.toBean(formSummary.getParamData(), OldPeopleSeekPdfDTO.class);
        formSummary.setFillDate(pdfDTO.getInspectionDate());

        // 添加人员标签
//        List<PeopleTagDTO> specialMark = new ArrayList<>();
//        PeopleTagDTO tagDTO = new PeopleTagDTO();
//        tagDTO.setBusinessType(getSummaryType());
//        List<PeopleTagDTO.Dict> tags = new ArrayList<>();
//
//        // 是否残疾
//        if (pdfDTO.getDisabilityOrNot()) {
//            PeopleTagDTO.Dict dict = new PeopleTagDTO.Dict();
//            dict.setBusinessType("是否残疾");
//            dict.setName("残疾");
//            tags.add(dict);
//        }
//        // 是否独居、空巢
//        if (pdfDTO.getLiveAloneOrNot()) {
//            PeopleTagDTO.Dict dict = new PeopleTagDTO.Dict();
//            dict.setBusinessType("是否独居、空巢");
//            dict.setName("独居、空巢");
//            tags.add(dict);
//        }
//        // 是否失能
//        if (pdfDTO.getWhetherDisabled()) {
//            PeopleTagDTO.Dict dict = new PeopleTagDTO.Dict();
//            dict.setBusinessType("是否失能");
//            dict.setName("失能");
//            tags.add(dict);
//        }
//        // 是否计划生育特殊家庭老年人
//        if (pdfDTO.getFamilyPlanningForTheElderly()) {
//            PeopleTagDTO.Dict dict = new PeopleTagDTO.Dict();
//            dict.setBusinessType("是否计划生育特殊家庭老年人");
//            dict.setName("计划生育特殊家庭老年人");
//            tags.add(dict);
//        }
//
//        tagDTO.setTag(tags);
//        specialMark.add(tagDTO);
        PersonInfo personInfo = personInfoService.fetch(pdfDTO.getId());
        if (personInfo == null) throw new ServiceException("人员信息不存在");
//        personInfo.setSpecialMark(JSONUtil.toList(JSONUtil.toJsonStr(specialMark), PersonnelTagDTO.class));

        // 设置紧急联系人
        personInfo.setEmergencyPeople(pdfDTO.getEmergencyContact());
        personInfo.setEmergencyPhone(pdfDTO.getEmergencyContactNumber());

        personInfoService.updateIgnoreNull(personInfo);

        completeFlowDataDTO.setFormSummary(formSummary);
        completeFlowDataDTO.setCompleteFlow(dto.getCompleteFlow());
        paramForController.setCompleteFlowDataDTO(completeFlowDataDTO);
        paramForController.setUserId(SecurityUtil.getUserId());
        // 创建任务
        summarySafetyCommponent.createOneTask(dto, null, getSummaryType());
        // 创建pdf
        super.createPdfAndMsg(paramForController);
    }

    /**
     * 更新 2.0版本
     * @param dto
     */
    public void update(TemplateCodeUpdateDTO dto) {
        log.info("白云区老年人探访更新：{}", JSONUtil.toJsonStr(dto));

        sqfwFormsummaryNewService.updateIgnoreNull(dto.getFormSummary());
        //Sqfw_formSummary_new formSummaryNew = sqfwFormsummaryNewService.fetch(dto.getFormSummary().getId());
        CompleteFlowPdfParamForController paramForController = new CompleteFlowPdfParamForController();
        CompleteFlowTemplateCodeUpdateDTO updateDTO = new CompleteFlowTemplateCodeUpdateDTO();

        // 设置上访时间
        Sqfw_formSummary_new formSummary = dto.getFormSummary();
        formSummary.setType(this.getSummaryType());
        OldPeopleSeekPdfDTO pdfDTO = JSONUtil.toBean(formSummary.getParamData(), OldPeopleSeekPdfDTO.class);
        formSummary.setFillDate(pdfDTO.getInspectionDate());

        // 添加人员标签
//        List<PeopleTagDTO> specialMark = new ArrayList<>();
//        PeopleTagDTO tagDTO = new PeopleTagDTO();
//        tagDTO.setBusinessType(getSummaryType());
//        List<PeopleTagDTO.Dict> tags = new ArrayList<>();
//
//        // 是否残疾
//        if (pdfDTO.getDisabilityOrNot()) {
//            PeopleTagDTO.Dict dict = new PeopleTagDTO.Dict();
//            dict.setBusinessType("是否残疾");
//            dict.setName("残疾");
//            tags.add(dict);
//        }
//        // 是否独居、空巢
//        if (pdfDTO.getLiveAloneOrNot()) {
//            PeopleTagDTO.Dict dict = new PeopleTagDTO.Dict();
//            dict.setBusinessType("是否独居、空巢");
//            dict.setName("独居、空巢");
//            tags.add(dict);
//        }
//        // 是否失能
//        if (pdfDTO.getWhetherDisabled()) {
//            PeopleTagDTO.Dict dict = new PeopleTagDTO.Dict();
//            dict.setBusinessType("是否失能");
//            dict.setName("失能");
//            tags.add(dict);
//        }
//        // 是否计划生育特殊家庭老年人
//        if (pdfDTO.getFamilyPlanningForTheElderly()) {
//            PeopleTagDTO.Dict dict = new PeopleTagDTO.Dict();
//            dict.setBusinessType("是否计划生育特殊家庭老年人");
//            dict.setName("计划生育特殊家庭老年人");
//            tags.add(dict);
//        }
//
//        tagDTO.setTag(tags);
//        specialMark.add(tagDTO);
        PersonInfo personInfo = personInfoService.fetch(pdfDTO.getId());
        if (personInfo == null) throw new ServiceException("人员信息不存在");
//        personInfo.setSpecialMark(JSONUtil.toList(JSONUtil.toJsonStr(specialMark), PersonnelTagDTO.class));

        // 设置紧急联系人
        personInfo.setEmergencyPeople(pdfDTO.getEmergencyContact());
        personInfo.setEmergencyPhone(pdfDTO.getEmergencyContactNumber());

        personInfoService.updateIgnoreNull(personInfo);

        updateDTO.setFormSummary(formSummary);
        paramForController.setCompleteFlowDataDTO(updateDTO);
        paramForController.setCompleteFlowId(formSummary.getSqfwFlowId());
        paramForController.setUserId(SecurityUtil.getUserId());
        super.reCreatePdfAndMsg(paramForController);
    }

    /**
     * 根据completeFlowId重新生成pdf
     *
     * @param completeFlowId
     */
    public void reCreatePdfAndMsg(String completeFlowId) {
        CompleteFlowPdfParamForController paramForController = new CompleteFlowPdfParamForController();
        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_formSummary_new::getSqfwFlowId, "=", completeFlowId);
        Sqfw_formSummary_new formSummaryNew = sqfwFormsummaryNewService.fetch(cnd);
        if (formSummaryNew == null) {
            throw new RuntimeException("数据不存在");
        }
        paramForController.setUserId(formSummaryNew.getCreateBy());
        paramForController.setCompleteFlowId(completeFlowId);
        super.reCreatePdfAndMsg(paramForController);
    }

    /**
     * 获取探访人最新一条探访记录
     * @return
     */
    public Sqfw_formSummary_new getLatest(String personInfoId) {
        Cnd cnd = Cnd.NEW();
        //cnd.and(Sqfw_formSummary_new::getCreateBy, "=", SecurityUtil.getUserId());
        cnd.and(Sqfw_formSummary_new::getType, "=", this.getSummaryType());
        cnd.and("param_data->>'id'", "=", personInfoId);
        cnd.desc(Sqfw_formSummary_new::getFillDate);
        return sqfwFormsummaryNewService.fetch(cnd);
    }

    /**
     * 获取列表数据 2.0版本
     * @return
     */
    public Result<?> list(Integer pageNo, Integer pageSize, String fillDate, String sort, String personInfoId, String careCategory) {
        SummaryQueryReqVo dto = new SummaryQueryReqVo();
        dto.setPageNo(pageNo);
        dto.setPageSize(pageSize);
        dto.setSort(sort);
        dto.setFillDate(fillDate);
        dto.setFillType(getSummaryType());

        if (StringUtils.isNotBlank(personInfoId) || StringUtils.isNotBlank(careCategory)) {
            SqlExpressionGroup sqlExpressionGroup = new SqlExpressionGroup();
            if (StringUtils.isNotBlank(personInfoId)) {
                sqlExpressionGroup.and("param_data->>'id'", "=", personInfoId);
            }
            if (StringUtils.isNotBlank(careCategory)) {
                SqlExpressionGroup expressionGroup = new SqlExpressionGroup();
                String careCategoryList[] = careCategory.split(",");
                int i = 0;
                for (String v : careCategoryList) {
                    if (i == 0) {
                        expressionGroup.and("param_data->'careCategory'", "@>", "[\""+v+"\"]");
                    } else {
                        expressionGroup.or("param_data->'careCategory'", "@>", "[\""+v+"\"]");
                    }

                }
                sqlExpressionGroup.and(expressionGroup);
            }

            dto.setSqlExpressionGroup(sqlExpressionGroup);
        }

        return summarySafetyService.listSummaryByPage(dto);
    }

    /**
     * pdf合集下载（通过sqfwIdList下载pdf合集）2.0版本 app端
     *
     * @param reqVo
     * @return
     */
    public List<ResultOfExcelGenerator> downPdfList(DownExcelLedgerReqVo reqVo) {
        List<ExcelCreateConfig> excelConfigList = new ArrayList<>();
        if (reqVo.isDownTemplate()) {
            ExcelCreateConfig config = new ExcelCreateConfig();
            config.setFileIdentity(reqVo.getFileCode());
            config.setOnlyGenerateTemplateFlag(true);
            excelConfigList.add(config);
        } else {
            Map<String,Object> param = new HashMap<>();
            param.put("start", reqVo.getFillStartDate());
            param.put("end", reqVo.getFillEndDate());
            param.put("personInfoId", reqVo.getQueryKey());
            if (reqVo.isCheckData()) {
                for (OldPeopleSeekEnum pdf : OldPeopleSeekEnum.getPdf()) {
                    ExcelCreateConfig config = new ExcelCreateConfig();
                    config.setFileIdentity(pdf.getCode());
                    config.setCreateExcelFileFlag(false);
                    config.setParam(param);
                    excelConfigList.add(config);
                }
            } else {
                ExcelCreateConfig config = new ExcelCreateConfig();
                config.setFileIdentity(reqVo.getFileCode());
                config.setCreateExcelFileFlag(true);
                config.setParam(param);
                excelConfigList.add(config);
            }
        }
        List<GenerateExcelUrlVO> voList = downPdfList(excelConfigList, null);
        List<ResultOfExcelGenerator> resultList = new ArrayList<>();
        for (GenerateExcelUrlVO vo : voList) {
            ResultOfExcelGenerator result = new ResultOfExcelGenerator();
            result.setExcelUrl(vo.getExcelUrl());
            result.setFileIdentity(vo.getFileIdentity());
            result.setPassCreateConditionFlag(vo.getCreateConditionFlag());
            resultList.add(result);
        }

        return resultList;
    }

    public void createPdfAndMsg(TemplateCodeUpdateDTO templateCodeUpdateDTO) {
        CompleteFlowPdfParamForController paramForController = new CompleteFlowPdfParamForController();
        CompleteFlowTemplateCodeUpdateDTO dto = new CompleteFlowTemplateCodeUpdateDTO();
        dto.setCompleteFlow(templateCodeUpdateDTO.getCompleteFlow());
        dto.setFormSummary(templateCodeUpdateDTO.getFormSummary());
        paramForController.setCompleteFlowDataDTO(dto);
        paramForController.setUserId(SecurityUtil.getUserId());
        super.createPdfAndMsg(paramForController);
    }

    /**
     * 获取回显列表
     * @param name
     * @return
     */
    public List<Record> echo(String name) {
        if (StringUtils.isBlank(name)) return new ArrayList<>();

        String userId = SecurityUtil.getUserId();
        Sys_user user = sysUserService.fetch(userId);

        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_formSummary_new::getProvince, "=", user.getProvince());
        cnd.and(Sqfw_formSummary_new::getCity, "=", user.getCity());
        cnd.and(Sqfw_formSummary_new::getDistrict, "=", user.getDistrict());
        cnd.and(Sqfw_formSummary_new::getCounty, "=", user.getCounty());
        cnd.and(Sqfw_formSummary_new::getCommunity, "=", user.getCommunity());
        cnd.and("param_data->>'nameOfTheInterviewee'", "like", "%"+ name +"%");
        cnd.groupBy("param_data->>'nameOfTheInterviewee'", "param_data->>'operatorTelephone'");

        String sql1 = "select max(param_data->>'inspectionDate') t,param_data->>'nameOfTheInterviewee' n " +
                "from shequ.sqfw_form_summary_new" + cnd + " limit 20";

        String sql2 = "select f.id, f.param_data->>'nameOfTheInterviewee' as name," +
                "f.param_data->>'operatorTelephone' as phone, f.param_data->>'inspectionDate' as time " +
                "from shequ.sqfw_form_summary_new  f right join ("+ sql1 +") tt "+
                "on f.param_data->>'nameOfTheInterviewee'=tt.n and f.param_data->>'inspectionDate'=tt.t";

        List<Record> records = sqfwFormsummaryNewService.list(Sqls.create(sql2));

        return records;
    }

    public Sqfw_formSummary_new get(String id) {
        return sqfwFormsummaryNewService.fetch(id);
    }

    @Override
    public GeneratorPdfWordResult createPdfSync(CompleteFlowPdfParamForController paramForController) {
        return super.createPdfSync(paramForController);
    }

    /**
     * pdf合集下载（通过表：sqfw_form_summary_new 的 id 下载pdf合集）
     * @param excelConfigList
     * @param summaryIds
     * @return
     */
    public List<GenerateExcelUrlVO> downPdfListToSummaryIds(List<ExcelCreateConfig> excelConfigList, List<String> summaryIds) {

        List<GenerateExcelUrlVO> generateExcelUrlVOS = new ArrayList<>();

        String sql = "select sc.resource_path from shequ.sqfw_completeflow sc left join shequ.sqfw_form_summary_new sfsn " +
                "on sc.id = sfsn.sqfw_flow_id where " +
                "sfsn.id in " + StrUtil.formatIds(summaryIds) +
                "and sc.resource_path != 'error' and sc.resource_path != 'creating' ";
        sql += "order by fill_date asc";
        List<Sqfw_completeflow> completeFlowList = sqfwCompleteflowService.listEntity(Sqls.create(sql));

        for (ExcelCreateConfig config : excelConfigList) {

            String fileName = OldPeopleSeekEnum.getCompilationName(config.getFileIdentity());

            // 模板下载
            if (config.getOnlyGenerateTemplateFlag()) {
                GenerateExcelUrlVO urlVO = new GenerateExcelUrlVO();
                String url = downWordTemplate(config);
                urlVO.setExcelUrl(url);
                generateExcelUrlVOS.add(urlVO);
                return generateExcelUrlVOS;
            }

            GenerateExcelUrlVO generateExcelUrlVO = new GenerateExcelUrlVO();
            generateExcelUrlVO.setFileIdentity(config.getFileIdentity());

            if (completeFlowList != null && completeFlowList.size() > 0) {
                generateExcelUrlVO.setCreateConditionFlag(true);
            } else {
                generateExcelUrlVO.setCreateConditionFlag(false);
            }

            // 数据检测
            if (!config.getCreateExcelFileFlag() || completeFlowList == null || completeFlowList.size() == 0) {
                generateExcelUrlVOS.add(generateExcelUrlVO);
                continue;
            }

            List<String> pdfList = completeFlowList.stream().map(Sqfw_completeflow::getResourcePath).collect(Collectors.toList());

            try {
                String url = createConvergePdfAndUpload(pdfList, fileName);
                generateExcelUrlVO.setExcelUrl(url);
            } catch (Exception e) {
                e.printStackTrace();
            }
            generateExcelUrlVOS.add(generateExcelUrlVO);
        }

        return generateExcelUrlVOS;
    }

    /**
     * pdf合集下载（通过sqfwIdList下载pdf合集）
     * @param excelConfigList
     * @param sqfwIdList
     * @return
     */
    public List<GenerateExcelUrlVO> downPdfList(List<ExcelCreateConfig> excelConfigList, List<String> sqfwIdList) {

        List<GenerateExcelUrlVO> generateExcelUrlVOS = new ArrayList<>();

        List<Sqfw_completeflow> completeFlowList = null;

        ExcelCreateConfig config0 = excelConfigList.get(0);

        if (!config0.getOnlyGenerateTemplateFlag()) {
            if (sqfwIdList == null || sqfwIdList.size() == 0) {
                String sql = "select sc.resource_path from shequ.sqfw_completeflow sc left join shequ.sqfw_form_summary_new sfsn " +
                        "on sc.id = sfsn.sqfw_flow_id where " +
                        "sfsn.create_by ='" + SecurityUtil.getUserId() + "' and sfsn.type = '" + this.getSummaryType() +
                        "' and sc.resource_path != 'error' and sc.resource_path != 'creating' ";
                if (config0.getParam().get("start") != null && StringUtils.isNotBlank(config0.getParam().get("start").toString())) {
                    sql += " and fill_date >= '" + config0.getParam().get("start").toString() + "'";
                }
                if (config0.getParam().get("end") != null && StringUtils.isNotBlank(config0.getParam().get("end").toString())) {
                    sql += " and fill_date <= '" + config0.getParam().get("end").toString() + " 23:59:59'";
                }
                if (config0.getParam().get("personInfoId") != null && StringUtils.isNotBlank(config0.getParam().get("personInfoId").toString())) {
                    sql += " and param_data->>'id' = '" + config0.getParam().get("personInfoId").toString() + "'";
                }
                sql += " order by fill_date asc";
                completeFlowList = sqfwCompleteflowService.listEntity(Sqls.create(sql));
            } else {
                String sql = "select sc.resource_path from shequ.sqfw_completeflow sc left join shequ.sqfw_form_summary_new sfsn " +
                        "on sc.id = sfsn.sqfw_flow_id where " +
                        "sc.sqfw_id in" + StrUtil.formatIds(sqfwIdList) +
                        "and sc.resource_path != 'error' and sc.resource_path != 'creating' ";
                sql += "order by fill_date asc";
                completeFlowList = sqfwCompleteflowService.listEntity(Sqls.create(sql));
            }
        }

        for (ExcelCreateConfig config : excelConfigList) {

            // 模板下载
            if (config.getOnlyGenerateTemplateFlag()) {
                GenerateExcelUrlVO urlVO = new GenerateExcelUrlVO();
                String url = downWordTemplate(config);
                urlVO.setExcelUrl(url);
                generateExcelUrlVOS.add(urlVO);
                return generateExcelUrlVOS;
            }

            // 数据下载
            String fileName = OldPeopleSeekEnum.getCompilationName(config.getFileIdentity());

            GenerateExcelUrlVO generateExcelUrlVO = new GenerateExcelUrlVO();
            generateExcelUrlVO.setFileIdentity(config.getFileIdentity());

            if (completeFlowList != null && completeFlowList.size() > 0) {
                generateExcelUrlVO.setCreateConditionFlag(true);
            } else {
                generateExcelUrlVO.setCreateConditionFlag(false);
            }

            // 数据检测
            if (!config.getCreateExcelFileFlag() || completeFlowList == null || completeFlowList.size() == 0) {
                generateExcelUrlVOS.add(generateExcelUrlVO);
                continue;
            }

            List<String> pdfList = completeFlowList.stream().map(Sqfw_completeflow::getResourcePath).collect(Collectors.toList());

            try {
                String url = createConvergePdfAndUpload(pdfList, fileName);
                generateExcelUrlVO.setExcelUrl(url);
            } catch (Exception e) {
                e.printStackTrace();
            }
            generateExcelUrlVOS.add(generateExcelUrlVO);
        }

        return generateExcelUrlVOS;
    }

    /**
     * 获取单位下所有pdf数据
     * @param excelConfigList
     * @return
     */
    public List<GenerateExcelUrlVO> downPdfListToUnit(List<ExcelCreateConfig> excelConfigList) {
        Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());

        List<GenerateExcelUrlVO> generateExcelUrlVOS = new ArrayList<>();

        String sql = "select sc.resource_path from shequ.sqfw_completeflow sc left join shequ.sqfw_form_summary_new sfsn " +
                "on sc.id = sfsn.sqfw_flow_id where sfsn.type = '" + getSummaryType() + "'" +
                " and sfsn.unit_id = '" + user.getUnitId() + "'" +
                " and sc.resource_path != 'error' and sc.resource_path != 'creating' ";
        sql += "order by fill_date asc";
        List<Sqfw_completeflow> completeFlowList = sqfwCompleteflowService.listEntity(Sqls.create(sql));

        for (ExcelCreateConfig config : excelConfigList) {

            // 模板下载
            if (config.getOnlyGenerateTemplateFlag()) {
                GenerateExcelUrlVO urlVO = new GenerateExcelUrlVO();
                String url = downWordTemplate(config);
                urlVO.setExcelUrl(url);
                generateExcelUrlVOS.add(urlVO);
                return generateExcelUrlVOS;
            }

            String fileName = OldPeopleSeekEnum.getCompilationName(config.getFileIdentity());

            GenerateExcelUrlVO generateExcelUrlVO = new GenerateExcelUrlVO();
            generateExcelUrlVO.setFileIdentity(config.getFileIdentity());

            if (completeFlowList != null && completeFlowList.size() > 0) {
                generateExcelUrlVO.setCreateConditionFlag(true);
            } else {
                generateExcelUrlVO.setCreateConditionFlag(false);
            }

            // 数据检测
            if (!config.getCreateExcelFileFlag() || completeFlowList == null || completeFlowList.size() == 0) {
                generateExcelUrlVOS.add(generateExcelUrlVO);
                continue;
            }

            List<String> pdfList = completeFlowList.stream().map(Sqfw_completeflow::getResourcePath).collect(Collectors.toList());

            try {
                String url = createConvergePdfAndUpload(pdfList, fileName);
                generateExcelUrlVO.setExcelUrl(url);
            } catch (Exception e) {
                e.printStackTrace();
            }
            generateExcelUrlVOS.add(generateExcelUrlVO);
        }

        return generateExcelUrlVOS;
    }

    /**
     * 获取用户自定义字段 代码生成器已经自动填充
     * 无需特殊修改
     *
     * @param paramData json字符串
     * @return 结果
     */
    @Override
    protected AbstractCustomerPdfCreateField getCustomerPdfField(String paramData) {
        return JSONObject.parseObject(paramData, OldPeopleSeekPdfDTO.class);
    }

    /**
     * 允许用户自定义填充在创建pdf时所提供的数据
     *
     * @param pdfGenerateParam 创建pdf所提供的数据
     */
    @Override
    protected void customerPopularPdfGenerateParam(PdfGenerateParam pdfGenerateParam) {
        Map<String, Object> customerParamMap = new HashMap<>();
        getLoveNumAndSeekNum(pdfGenerateParam, customerParamMap);
        getPeopleNum(pdfGenerateParam, customerParamMap);
        pdfGenerateParam.setCustomerParamMap(customerParamMap);
    }

    /**
     * 在这里设置生成pdf的所有generator
     *
     * @param pdfGenerateParam 创建pdf的参数
     * @return 生成pdf的generator合集
     */
    @Override
    protected List<BasePdfGenerator> getPdfGenerator(PdfGenerateParam pdfGenerateParam) {
        List<BasePdfGenerator> generatorList = Lists.newArrayList();
        // 在这里添加自己的generator
        generatorList.add(new OldPeopleSeekPdfGenerator());
        return generatorList;
    }

    /**
     * 用户自定义下载pdf文件的名称
     *
     * @param pdfGenerateParam 创建pdf所提供的参数
     * @return 结果
     */
    @Override
    protected String getDownloadFileName(PdfGenerateParam pdfGenerateParam) {
        return OldPeopleSeekEnum.CARE_SERVICE_RECORD_PDF.getOneName();
    }

    /**
     * 第五张表中的需要的类型，详情见 {@link com.budwk.app.sqfw.constants.SqfwFormSummaryConstants}
     *
     * @return 返回数据
     */
    @Override
    public String getSummaryType() {
        return SqfwFormSummaryConstants.old_people_seek;
    }

    /**
     * 下载word模板
     * @param config
     * @return
     */
    private String downWordTemplate(ExcelCreateConfig config) {
        String fileName = OldPeopleSeekEnum.getTemplateName(config.getFileIdentity());

        Map<String, Object> dataMap = JSONUtil.parseObj(new Sqfw_formSummary_new(), false);
        dataMap.putAll(JSONUtil.parseObj(new OldPeopleSeekPdfDTO(), false));
        List<NiceXWPFDocument> xwpfDocumentList = new ArrayList<>();

        if (OldPeopleSeekEnum.CARE_SERVICE_RECORD_PDF.getCode().equals(config.getFileIdentity())) {
            xwpfDocumentList.add(getNiceXWPFDocument(dataMap, new OldPeopleSeekPdfGenerator().getTemplatePath(null)));
        }

        GenerateWordAndPdfUrlVO vo = CommonFormOfficeUtils.wordUpload(xwpfDocumentList, fileName);
        return vo.getWordUrl();
    }

    /**
     * 生成单个word
     * @param dataMap
     * @param templateName
     * @return
     */
    private NiceXWPFDocument getNiceXWPFDocument(Map<String, Object> dataMap, String templateName) {
        for (String key : dataMap.keySet()) {
            dataMap.put(key, "");
        }

        String fieldName = ClassUtil.getField(OldPeopleSeekPdfDTO::getCheckedUnitLeader);
        dataMap.put(fieldName + "s", new ArrayList<>());
        dataMap.put("signatures", new ArrayList<>());

        dataMap.put("yyyy", "  ");
        dataMap.put("mm", "  ");
        dataMap.put("dd", "  ");
        dataMap.put("loveNum", "");
        dataMap.put("seekNum", "");
        dataMap.put("peopleNum", 0.1);

        String lists[] = new OldPeopleSeekPdfGenerator().getListKey();
        dataMap.put(lists[0], OldPeopleSeekPdfGenerator.getFamilyInformation(new OldPeopleSeekPdfDTO()));

        // word表格设置
        Map<String, RenderPolicy> renderPolicyMap = Maps.newHashMap();
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        renderPolicyMap.put(lists[0], policy);

        XWPFTemplate xwpfTemplate = generateWordDocument(dataMap, null, renderPolicyMap, templateName);
        return xwpfTemplate.getXWPFDocument();
    }

    /**
     * 获取探访次数
     * 1、通过被探访人姓名来计算此次为第几次开展探访
     * 2、通过被探访人姓名来计算此次为第几次开展关爱
     * @param pdfGenerateParam
     * @return
     */
    private Map<String, Object> getLoveNumAndSeekNum(PdfGenerateParam pdfGenerateParam, Map<String, Object> map) {
        CommonParam param = pdfGenerateParam.getCreateUserCommonParam();
        OldPeopleSeekPdfDTO dto = (OldPeopleSeekPdfDTO) pdfGenerateParam.getAbstractCustomerPdfCreateField();

        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_formSummary_new::getProvince, "=", param.getProvince());
        cnd.and(Sqfw_formSummary_new::getCity, "=", param.getCity());
        cnd.and(Sqfw_formSummary_new::getDistrict, "=", param.getDistrict());
        cnd.and(Sqfw_formSummary_new::getCounty, "=", param.getCounty());
        cnd.and(Sqfw_formSummary_new::getCommunity, "=", param.getCommunity());
        cnd.and("param_data->>'nameOfTheInterviewee'", "=", dto.getNameOfTheInterviewee());
        cnd.and("param_data->>'operatorTelephone'", "=", dto.getOperatorTelephone());

        String sql = "select id from shequ.sqfw_form_summary_new " + cnd;

        List<Sqfw_formSummary_new> summaryList = sqfwFormsummaryNewService.listEntity(Sqls.create(sql));
        if (summaryList == null || summaryList.size() == 0) {
            map.put("loveNum", 1);
            map.put("seekNum", 1);
        } else {
            map.put("loveNum", summaryList.size());
            map.put("seekNum", summaryList.size());
        }
       return map;
    }

    /**
     * 获取家庭人数变化情况
     * 后续探访时，根据本次“家庭人口”字段与上一次“家庭人口”字段做对比作计算
     * @param pdfGenerateParam
     * @return
     */
    private Map<String, Object> getPeopleNum(PdfGenerateParam pdfGenerateParam, Map<String, Object> map) {
        CommonParam param = pdfGenerateParam.getCreateUserCommonParam();
        OldPeopleSeekPdfDTO dto = (OldPeopleSeekPdfDTO) pdfGenerateParam.getAbstractCustomerPdfCreateField();

        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_formSummary_new::getProvince, "=", param.getProvince());
        cnd.and(Sqfw_formSummary_new::getCity, "=", param.getCity());
        cnd.and(Sqfw_formSummary_new::getDistrict, "=", param.getDistrict());
        cnd.and(Sqfw_formSummary_new::getCounty, "=", param.getCounty());
        cnd.and(Sqfw_formSummary_new::getCommunity, "=", param.getCommunity());
        cnd.and("param_data->>'nameOfTheInterviewee'", "=", dto.getNameOfTheInterviewee());
        cnd.and("param_data->>'operatorTelephone'", "=", dto.getOperatorTelephone());
        cnd.and("(param_data->>'inspectionDate')::int8", "<", dto.getInspectionDate().getTime());
        cnd.orderBy("param_data->>'inspectionDate'", "desc");

        String sql = "select * from shequ.sqfw_form_summary_new " + cnd + " limit 1";

        List<Sqfw_formSummary_new> summaryList = sqfwFormsummaryNewService.listEntity(Sqls.create(sql));
        if (summaryList == null || summaryList.size() == 0) {
            map.put("peopleNum", 0);
        } else {
            Sqfw_formSummary_new summaryNew = summaryList.get(0);
            OldPeopleSeekPdfDTO lastDto = JSONUtil.toBean(summaryNew.getParamData(), OldPeopleSeekPdfDTO.class);
            int size = dto.getFamilyInformation() == null ? 0 : dto.getFamilyInformation().size();
            int lastSize = lastDto.getFamilyInformation() == null ? 0 : lastDto.getFamilyInformation().size();
            map.put("peopleNum", size - lastSize);
        }
        return map;
    }


    /**
     * 添加人员信息
     * @param personInfo
     * @return
     */
    public Result<?> addPersonInfo(PersonInfo personInfo) {
        Sys_user sysUser = sysUserService.getUserById(SecurityUtil.getUserId());

        Cnd cnd = Cnd.NEW();
        cnd.and(PersonInfo::getName, "=", personInfo.getName());
        cnd.and(PersonInfo::getCommunity, "=", sysUser.getCommunity());
        cnd.and(PersonInfo::getAddress, "=", personInfo.getAddress());
        PersonInfo person = personInfoService.fetch(cnd);
        if (person != null) return Result.success("该人员已存在");

        personInfo.setBusinessType(this.getSummaryType());
        personInfo.setUnitName(sysUser.getUnitName());
        personInfo.setProvince(sysUser.getProvince());
        personInfo.setCity(sysUser.getCity());
        personInfo.setDistrict(sysUser.getDistrict());
        personInfo.setCounty(sysUser.getCounty());
        personInfo.setCommunity(sysUser.getCommunity());
        personInfo.setCreateBy(sysUser.getId());
        personInfo.setCreateDate(LocalDateTime.now());
        personInfo.setAge(DateUtil.ageOfNow(new DateTime(personInfo.getBirthDate())));
        return Result.data(personInfoService.insert(personInfo));
    }

    /**
     * 更新人员信息
     * @param personInfo
     * @return
     */
    public Result<?> updatePersonInfo(PersonInfo personInfo) {
        Sys_user sysUser = sysUserService.getUserById(SecurityUtil.getUserId());

        Cnd cnd = Cnd.NEW();
        cnd.and(PersonInfo::getId, "!=", personInfo.getId());
        cnd.and(PersonInfo::getName, "=", personInfo.getName());
        cnd.and(PersonInfo::getCommunity, "=", sysUser.getCommunity());
        cnd.and(PersonInfo::getAddress, "=", personInfo.getAddress());
        PersonInfo person = personInfoService.fetch(cnd);
        if (person != null) return Result.success("该人员已存在");

        personInfo.setUpdateBy(SecurityUtil.getUserId());
        personInfo.setUpdateDate(LocalDateTime.now());
        personInfo.setAge(DateUtil.ageOfNow(new DateTime(personInfo.getBirthDate())));
        personInfoService.updateIgnoreNull(personInfo);
        return Result.data(personInfo);
    }

    /**
     * 获取人员列表
     * @param pageNo
     * @param pageSize
     * @param query
     * @param category
     * @return
     */
    public Pagination pagePersonInfo(Integer pageNo, Integer pageSize, String query, String category) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("select * from shequ.sqfw_person_info where ");
        stringBuilder.append("business_type like '%");
        stringBuilder.append(this.getSummaryType()).append("%'");
        // 设置5级区域查询
        String five = CommonCheckUtils.getLv5();
        if (StringUtils.isNotBlank(five)) {
            stringBuilder.append(five);
        }
        if (StringUtils.isNotBlank(query)) {
            stringBuilder.append(" and ");
            stringBuilder.append("(name like '%"+query+"%' or id_number like '%"+query+"%')");
        }
        if (StringUtils.isNotBlank(category)) {
            stringBuilder.append(" and ");
            stringBuilder.append("EXISTS (SELECT 1 FROM jsonb_array_elements(special_mark::jsonb) AS elem WHERE elem->>'businessType' ='");
            stringBuilder.append(this.getSummaryType()).append("'");
            stringBuilder.append("and elem->'tag' @> '");
            String categoryList[] = category.split(",");
            List<Map<String, Object>> mapList = new ArrayList<>();
            for (String s : categoryList) {
                mapList.add(Map.of("name", s));
            }
            stringBuilder.append(JSONUtil.toJsonStr(mapList));
            stringBuilder.append("')");
        }
        stringBuilder.append(" order by create_date desc");
        Pagination pagination = personInfoService.listPageEntity(pageNo, pageSize, Sqls.create(stringBuilder.toString()));
        return pagination;
    }
}
